package com.snail.config;

import com.snail.constants.RabbitMqConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Monica
 * @description
 * @date 2025/7/19 14:05
 */
@Slf4j
@Configuration
public class RabbitMqConfig {


    @Bean
    public MessageConverter messageConverter() {
        // 1.定义消息转换器
        Jackson2JsonMessageConverter jjmc = new Jackson2JsonMessageConverter();
        // 2.配置自动创建消息id，用于识别不同消息，也可以在业务中基于ID判断是否是重复消息
        jjmc.setCreateMessageIds(true);
        return jjmc;
    }

//    @Bean
//    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
//        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//
//        // 关键！设置 JSON 消息转换器
//        // 必须手动
//        rabbitTemplate.setMandatory(true);
//        rabbitTemplate.setMessageConverter(messageConverter);
//        // 启用 Confirm 机制
//        rabbitTemplate.setConfirmCallback((correlationData, ack, errMsg) -> {
//        });
//        // 启用 Returns 机制
//        rabbitTemplate.setReturnsCallback(returned -> log.info("ReturnsCallback:     消息：{}", returned));
//
//        return rabbitTemplate;
//    }

    @Bean(RabbitMqConstants.VIDEO_DIRECT_EXCHANGE)
    public DirectExchange videoDirectExchange() {
        return new DirectExchange(RabbitMqConstants.VIDEO_DIRECT_EXCHANGE, true, false, null);
    }

    /**
     * 声明队列
     *
     * @return directQueue
     */
    @Bean(RabbitMqConstants.VIDEO_DIRECT_QUEUE)
    public Queue directQueue() {
        return new Queue(RabbitMqConstants.VIDEO_DIRECT_QUEUE, true, false, false);
    }

    /**
     * 绑定队列到交换机 .with指定routingkey
     *
     * @param directExchange 交换机
     * @param directQueue    队列
     * @return Binding
     */
    @Bean
    public Binding bindingDirect(@Qualifier(RabbitMqConstants.VIDEO_DIRECT_EXCHANGE) DirectExchange directExchange, @Qualifier(RabbitMqConstants.VIDEO_DIRECT_QUEUE) Queue directQueue) {
        return BindingBuilder.bind(directQueue).to(directExchange).with(RabbitMqConstants.VIDEO_DIRECT_ROUTING_KEY);
    }


    // 支付相关
    //声明交换机，且持久化
    @Bean(RabbitMqConstants.PAY_NOTIFY_EXCHANGE_FANOUT)
    public DirectExchange payNotifyExchangeFanout() {
        // 三个参数：交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
        return new DirectExchange(RabbitMqConstants.PAY_NOTIFY_EXCHANGE_FANOUT, true, false);
    }

    //支付通知队列,且持久化
    @Bean(RabbitMqConstants.PAY_NOTIFY_QUEUE)
    public Queue coursePublishQueue() {
        return QueueBuilder.durable(RabbitMqConstants.PAY_NOTIFY_QUEUE).build();
    }

    //交换机和支付通知队列绑定
    @Bean
    public Binding bindingCoursePublishQueue(@Qualifier(RabbitMqConstants.PAY_NOTIFY_QUEUE) Queue queue, @Qualifier(RabbitMqConstants.PAY_NOTIFY_EXCHANGE_FANOUT) DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstants.PAY_NOTIFY_ROUTING_KEY);
    }

//    @Override
//    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        // 获取RabbitTemplate
//        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
//        //消息处理service
//        MqMessageService mqMessageService = applicationContext.getBean(MqMessageService.class);
//        // 设置ReturnCallback
//        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
//            // 投递失败，记录日志
//            log.info("消息发送失败，应答码{}，原因{}，交换机{}，路由键{},消息{}",
//                    replyCode, replyText, exchange, routingKey, message.toString());
//            MqMessage mqMessage = JSON.parseObject(message.toString(), MqMessage.class);
//            //将消息再添加到消息表
//            mqMessageService.addMessage(mqMessage.getMessageType(),mqMessage.getBusinessKey1(),mqMessage.getBusinessKey2(),mqMessage.getBusinessKey3());
//
//        });
}
